package Ms

import (
	"database/sql"
	"errors"
	"fmt"
	"db2s/ETL"
	"db2s/global"
	"strconv"
)

type ConnActive struct {
}

// MaxConnectionSum 获取当前可用连接的最大连接数
func (c ConnActive) MaxConnectionSum(db *sql.DB) (int64, error) {
	var (
		tableData              map[string]interface{}
		maxAvailableConnection int64
		err                    error
	)
	active := ETL.InstanceActiveS{DBType: DBType, DB: db, SqlMode: true}
	strSql := fmt.Sprintf("select (select @@MAX_CONNECTIONS)-count(*) as 'maxAvailableConnection' from sys.dm_exec_connections")
	var f1 any
	if _, f1, err = active.SqlQuery(strSql, ETL.Map); err != nil {
		return 0, err
	} else {
		tableData = f1.(map[string]interface{})
	}
	if v, ok := tableData["maxAvailableConnection"]; ok {
		if maxAvailableConnection, err = strconv.ParseInt(fmt.Sprintf("%v", v), 10, 64); err != nil {
			maxAvailableConnection = 0
			return maxAvailableConnection, nil
		}
	}
	return maxAvailableConnection, nil
}

/*
连接数据库，返回连接内存地址
*/
func (c ConnActive) openDb(s global.Conn) (any, error) {
	var (
		maxConnectionSum int64
	)
	db, err := sql.Open(s.Device, s.Jdbc)
	if err != nil {
		newErr := errors.New(fmt.Sprintf("database open fail. case: %v", err))
		return nil, newErr
	}
	if err = db.Ping(); err != nil {
		newErr := errors.New(fmt.Sprintf("database connection fail. case: %v", err))
		return nil, newErr
	}
	db.SetMaxIdleConns(s.MaxIdle)
	db.SetMaxOpenConns(s.MaxOpen)
	if maxConnectionSum, err = c.MaxConnectionSum(db); err != nil {
		return nil, err
	} else {
		db.SetMaxOpenConns(int(maxConnectionSum / 2))
	}
	return map[string]any{"pointer": map[string]*sql.DB{"single": db}, "map": map[string]*sql.DB{"single": db}, "sum": map[string]int64{"single": maxConnectionSum}}, nil
}
func (c ConnActive) Open(s global.Conn) (any, error) {
	defer func() {
		if err1 := recover(); err1 != nil {
			fmt.Println("oracle database create session connection fail, Check the database connection information.err info is ", err1)
		}
	}()
	return c.openDb(s)
}

// Close 参数复原
func (c ConnActive) Close(_ map[string]*sql.DB) {

}
